{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Abstraction using ABCs:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Processing $100.0 payment via PayPal.\n",
      "Processing $200.0 payment via Stripe.\n"
     ]
    }
   ],
   "source": [
    "from abc import ABC, abstractmethod\n",
    "\n",
    "\n",
    "class PaymentProcessor(ABC):\n",
    "    @abstractmethod\n",
    "    def process_payment(self, amount: float) -> None:\n",
    "        pass\n",
    "\n",
    "\n",
    "class PayPalProcessor(PaymentProcessor):\n",
    "    def process_payment(self, amount: float) -> None:\n",
    "        print(f\"Processing ${amount} payment via PayPal.\")\n",
    "\n",
    "\n",
    "class StripeProcessor(PaymentProcessor):\n",
    "    def process_payment(self, amount: float) -> None:\n",
    "        print(f\"Processing ${amount} payment via Stripe.\")\n",
    "\n",
    "\n",
    "def process_order(amount: float, processor: PaymentProcessor) -> None:\n",
    "    processor.process_payment(amount)\n",
    "\n",
    "\n",
    "paypal = PayPalProcessor()\n",
    "stripe = StripeProcessor()\n",
    "process_order(100.0, paypal)\n",
    "process_order(200.0, stripe)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Abstracting a logger using a protocol:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LOG: Task started.\n",
      "LOG: Task completed.\n"
     ]
    }
   ],
   "source": [
    "from typing import Protocol\n",
    "\n",
    "\n",
    "class Logger(Protocol):\n",
    "    def log(self, message: str) -> None:\n",
    "        pass\n",
    "\n",
    "\n",
    "class ConsoleLogger:\n",
    "    def log(self, message: str) -> None:\n",
    "        print(f\"LOG: {message}\")\n",
    "\n",
    "\n",
    "class FileLogger:\n",
    "    def log(self, message: str) -> None:\n",
    "        with open(\"log.txt\", \"a\") as file:\n",
    "            file.write(f\"{message}\\n\")\n",
    "\n",
    "\n",
    "def perform_task(logger: Logger) -> None:\n",
    "    logger.log(\"Task started.\")\n",
    "    # Simulate a task\n",
    "    logger.log(\"Task completed.\")\n",
    "\n",
    "\n",
    "console_logger = ConsoleLogger()\n",
    "file_logger = FileLogger()\n",
    "perform_task(console_logger)  # Output: LOG: Task started. LOG: Task completed.\n",
    "perform_task(file_logger)  # Logs to a file."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
